package org.venus.onvif.util;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import de.onvif.soap.OnvifDevice;
import de.onvif.soap.devices.PtzDevices;
import org.onvif.ver10.schema.Profile;
import org.venus.onvif.config.Config;
import org.venus.onvif.entity.MediaServer;
import org.venus.onvif.entity.OnvifHelp;
import org.venus.onvif.entity.Video;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * Author      jxx
 * Motto       让世界看到我
 * On          2023/11/2 9:25
 * Version     v1.0
 * Note        TODO
 */
public class InitUtil {

    public static boolean initConfig() {
        FileOutputStream fos = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            String dir = System.getProperty("user.dir");
            System.out.println(dir);
            File configDir = new File(dir, "config");
            if (!configDir.exists()) {
                System.out.println("配置文件夹不存在,现在创建");
                configDir.mkdirs();
            }
            if (!configDir.isDirectory()) {
                System.out.println("配置文件夹类型异常,删除重新创建");
                configDir.delete();
                configDir.mkdirs();
            }
            //---------------------------------------设备配置文件----------------------------------------
            File dataFile = new File(configDir, "data.json");
            if (!dataFile.exists()) {
                System.out.println("设备配置文件不存在,先为您创建一个模板,稍后请先修改配置文件数据再运行程序!");
                boolean r = dataFile.createNewFile();
                if (!r) {
                    System.out.println("设备配置文件创建失败!");
                    return false;
                }
                List<Video> list = new ArrayList<>();
                for (int i = 1; i < 3; i++) {
                    Video video = new Video();
                    video.id = String.valueOf(i);
                    video.ip = "192.168.101.1" + i;
                    video.userName = "admin";
                    video.password = "admin12345";
                    video.rtsp = "rtsp://" + video.userName + ":" + video.password + "@" + video.ip;
                    list.add(video);
                }
                fos = new FileOutputStream(dataFile);
                osw = new OutputStreamWriter(fos, Charset.defaultCharset());
                bw = new BufferedWriter(osw);
                bw.write(JsonUtil.formatJson(new Gson().toJson(list)));
                bw.flush();
                System.out.println("创建设备配置文件模板成功:" + dataFile.getAbsolutePath());
            }
            Path path = Paths.get(dataFile.getAbsolutePath());
            byte[] bytes = Files.readAllBytes(path);
            String json = new String(bytes, Charset.defaultCharset());
            System.out.println("读取设备配置文件内容:");
            System.out.println(json);
            Type type = new TypeToken<List<Video>>() {
            }.getType();
            Config.videos = new Gson().fromJson(json, type);


            //---------------------------------------媒体服务器配置文件----------------------------------------
            File mediaFile = new File(configDir, "media.json");
            if (!mediaFile.exists()) {
                System.out.println("媒体服务器配置文件不存在,先为您创建一个模板,稍后请先修改配置文件数据再运行程序!");
                boolean r = mediaFile.createNewFile();
                if (!r) {
                    System.out.println("设备配置文件创建失败!");
                    return false;
                }
                MediaServer mediaServer = new MediaServer();
                mediaServer.ip = "192.168.101.100";
                mediaServer.port = 99;
                mediaServer.secret = "123456";
                mediaServer.ptzStep = 5;
                fos = new FileOutputStream(mediaFile);
                osw = new OutputStreamWriter(fos, Charset.defaultCharset());
                bw = new BufferedWriter(osw);
                bw.write(JsonUtil.formatJson(new Gson().toJson(mediaServer)));
                bw.flush();
                System.out.println("创建媒体服务器配置文件模板成功:" + mediaFile.getAbsolutePath());
            }
            Path pathMedia = Paths.get(mediaFile.getAbsolutePath());
            byte[] bytesMedia = Files.readAllBytes(pathMedia);
            String jsonMedia = new String(bytesMedia, Charset.defaultCharset());
            System.out.println("读取媒体服务器配置文件内容:");
            System.out.println(jsonMedia);
            Config.mediaServer = new Gson().fromJson(jsonMedia, MediaServer.class);

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            IOUtil.release(bw);
            IOUtil.release(osw);
            IOUtil.release(fos);
        }
    }

    public static void initOnvif() {
        for (Video video : Config.videos) {
            //创建每个设备的onvif对象,因为这个过程耗时比较多,每次调用都创建的话看起来会卡,因此将onvif对象在程序启动时创建出来,保存在内存中,接口调用时可以直接使用
            getOnvif(video.id);
        }
    }

    public static OnvifHelp getOnvif(String id) {
        if (id==null){
            return null;
        }
        try {
            OnvifHelp onvifHelp = Config.onvifDeviceHashMap.get(id);
            if (onvifHelp != null) {
                return onvifHelp;
            }
            onvifHelp = new OnvifHelp();
            Video video = Config.videos.stream().filter(item -> item.id.equals(id)).findFirst().get();
            onvifHelp.onvifDevice = new OnvifDevice(video.ip, video.userName, video.password);
            onvifHelp.onvifDevice.getSoap().setLogging(false);
            onvifHelp.profileToken = onvifHelp.onvifDevice.getDevices().getProfiles().get(0).getToken();
            onvifHelp.ptzDevices = onvifHelp.onvifDevice.getPtz();

            Config.onvifDeviceHashMap.put(id, onvifHelp);
            return onvifHelp;
        } catch (Exception e) {
            System.out.println("获取设备[" + id + "]onvif操作对象失败:" + e.getClass().getName() + "-->" + e.getMessage());
            System.out.println("请确认设备是否支持onvif云台控制,如果不支持可以忽略此错误");
            e.printStackTrace();
        }
        return null;
    }
}
